package com.headcaselabs.lb.director;

import java.util.Date;
import java.util.List;
import java.util.Set;

import com.headcaselabs.lb.common.Server;


/* 
Copyright 2007, HeadCase Humanufacturing, Inc.

	Licensed under the Apache License, Version 2.0 (the "License"); you
	may not use this file except in compliance with the License. You may
	obtain a copy of the License at
	
	   http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
	implied. See the License for the specific language governing
	permissions and limitations under the License.
*/
/**
 * Polls the database for changes and notifies the director if a change has been made. 
 * This allows to create a simple web based interface for adding and removing nodes which does not need to communicate via RMI. 
 * The changes will be detected at the latest after the number of milliseconds as specified in DirectorImpl.checkInterval.
 * @author Florian Leibert
 *
 */
public class DBPoll implements Runnable {

	private DirectorImpl director;
	private DBTools dbtools;
	/**
	 * Constructor
	 * @param director
	 * @param dbtools
	 * @param lock
	 */
	public DBPoll(DirectorImpl director, DBTools dbtools) {
		this.director = director;
		this.dbtools = dbtools;
	}
	
	public void run() {
		boolean init = true;
		while (true) {
			boolean update = false;
			if (!init) {
				try {
					synchronized(director.lock) {
						director.lock.wait(DirectorImpl.checkInterval);
					}
					director.log("Woke up, checking for changes");
				} catch (InterruptedException ie) {
					ie.printStackTrace();
				}
			} else {
				init = false;
			}
			Set<String> groupNames = director.servers.keySet();
			int numServers;
			
			for (String groupName : groupNames) {
				director.log("Checking group:"+groupName+" for changes...");
				numServers = director.servers.get(groupName).size();
				if (numServers!=dbtools.getGroupSize(groupName)||dbtools.isUpdated(groupName, director.getLastModify())) {
					List<Server> servers = dbtools.loadGroup(groupName);
					director.servers.remove(groupName);
					director.servers.put(groupName, servers);
					update = true;
				}
			}
			if (update) {
				director.log("Update found. Notifying clients.");
				director.updateRecords();
				director.setLastModify((new Date()).getTime());
			}
		}
	}

}
